
//Copyright 1997-2009 Syrinx Development, Inc.
//This file is part of the Syrinx Web Application Framework (SWAF).
// == BEGIN LICENSE ==
//
// Licensed under the terms of any of the following licenses at your
// choice:
//
//  - GNU General Public License Version 3 or later (the "GPL")
//    http://www.gnu.org/licenses/gpl.html
//
//  - GNU Lesser General Public License Version 3 or later (the "LGPL")
//    http://www.gnu.org/licenses/lgpl.html
//
//  - Mozilla Public License Version 1.1 or later (the "MPL")
//    http://www.mozilla.org/MPL/MPL-1.1.html
//
// == END LICENSE ==
using System;
using System.Xml;
using System.IO;

using Swaf;
using Swaf.BizRule;
using Swaf.BizObj;

using Swaf.Messaging;
using Swaf.Container;

namespace Swaf.Call
{
	/// <summary>
	/// Summary description for RuleMgrCall.
	/// </summary>
	public class MessagingRuleMgrCall : BaseCall
	{
		protected IMessagingSystem m_helper;

		protected string m_provider="";
		protected string m_connection="";
		//protected string m_queueManager="";
		protected string m_destination="";
		protected string m_replyQueueManager="";
		protected string m_replyDestination="";
		protected string m_format="Text";
		protected string m_msgBody;


		public static string RuleMessageIdentifier = "[RuleCallMessage]";
		private static string s_callFormat = RuleMessageIdentifier + "rulename={0}&param={1}&paramType={2}";

		static private IClassFactory s_messagingSystemFactory;
		private IClassFactory MessagingSystemFactory 
		{
			get
			{
				if(s_messagingSystemFactory == null)
					s_messagingSystemFactory = Application.currentApp.factories["MessagingSystems"];
				return s_messagingSystemFactory;
			}
		}
		
		public MessagingRuleMgrCall(string id, XmlElement initInfo)
			:base(id, initInfo)
		{
			string tempValue = "";			
			IApplication app = Application.currentApp;
			m_provider = app.resMgr.resolve(initInfo.GetAttribute("provider"));
			m_connection = app.resMgr.resolve(initInfo.GetAttribute("connection"));
			//m_queueManager = app.resMgr.resolve(initInfo.GetAttribute("queueManager"));
			m_destination = app.resMgr.resolve(initInfo.GetAttribute("destination"));
			m_replyQueueManager = app.resMgr.resolve(initInfo.GetAttribute("replyQueueManager"));
			m_replyDestination = app.resMgr.resolve(initInfo.GetAttribute("replyDestination"));
			tempValue=app.resMgr.resolve(initInfo.GetAttribute("format"));
			if (! tempValue.Equals(""))
				m_format=tempValue;
		}

		public override object call(params object[] p)
		{
			IApplication app = Application.currentApp;
			string returnMsg="";
			object callParams = this.calcCallParams(p);
			SerializationInfo paramInfo;
			IRunningRule r = ((IRuleManagerEx)app.ruleMgr).CurrentThreadRunningRule;
			IRuleInfo info = r.Info;
			string encrypt="none";

			//app.Log.println(String.Format("{0} type MessagingRuleMgrCall to connection {0} on Queue {1}", m_provider,m_connection, m_destination));
			if (info.Decorators.Contains("encrypt"))
			{
				GenericDecorator encryptDec=(GenericDecorator) info.Decorators["encrypt"];
				encrypt = (string) encryptDec.Value;
			}
			if (callParams.GetType() == typeof(object[]))
			{
				callParams = getParams(callParams);
				if (callParams!=null && callParams.GetType() == typeof(object[]) && ((object[])callParams).Length == 1)
				{
					paramInfo	= Serialization.serialize(((object[])callParams)[0]);
				}
				else
				{
					paramInfo	= Serialization.serialize(callParams);
				}
			}					
			else
			{
				paramInfo	= Serialization.serialize(callParams);
			}

			m_msgBody = String.Format(s_callFormat, app.resMgr.fixupForHttp(m_methodName), app.resMgr.fixupForHttp(paramInfo.SerialObject), paramInfo.TypeName);

			try
			{
				m_helper = (IMessagingSystem)MessagingSystemFactory.createFromNickName(m_provider);
			}
			catch(Exception e)
			{
				throw new CallException(
					String.Format("Unable to create messaging helper class '{0}' for MessagingRuleMgrCall", m_provider),e);
			}
			if ((! m_replyDestination.Equals("")) && (! m_replyQueueManager.Equals("")))
				returnMsg=m_helper.send(m_msgBody,encrypt, m_destination,m_connection,m_format,new FlexiMap(),m_replyDestination,m_replyQueueManager);
			else
				m_helper.send(m_msgBody,encrypt, m_destination,m_connection,m_format,new FlexiMap());

			if (! returnMsg.Equals(""))
			{
				XmlDocument doc = new XmlDocument();
				doc.LoadXml(returnMsg);
				if(doc.DocumentElement.Name.Equals("RuleCallResults"))
				{
					return BasicResults.createFromXml(doc.DocumentElement).CallResults;
				}
				else
				{
					return doc.DocumentElement;
				}
			}
			else
				return null;
		}

		private object getParams(object p)
		{
			object [] inParms;
			System.Type pType = p.GetType();
			if (!pType.IsArray)
			{
				inParms = new object[]{p}; 
			}
			else
			{
				inParms = (object[]) p;
			}
			try
			{
				if (inParms.Length != 0 && inParms[0].GetType() == typeof(Swaf.Application))
				{
					if (inParms.Length ==3)
					{
						if (inParms[2] == null)
						{
							return null;
						}
						else
						{
							return inParms[2];
						}
					}
					else
					{
						object[] newParams = new object[inParms.Length - 2];
						Array.Copy(inParms,2,newParams,0,newParams.Length);
						return newParams;
					}
				}
				else
				{
					return p;
				}
			}
			catch(Exception e)
			{
				System.Diagnostics.Debugger.Break();
				return p;
			}
		}
	}
}
